package com.ruoyi.system.service.impl;

import java.util.*;
import java.util.stream.Collectors;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.StatisticsMapper;
import com.ruoyi.system.service.IStatisticsService;

/**
 * 数据统计分析Service业务层处理
 *
 * @author ltr
 * @date 2024-11-19
 */
@Service
public class StatisticsServiceImpl implements IStatisticsService
{
    @Autowired
    private StatisticsMapper statisticsMapper;

    /**
     * 获取系统总体概览统计
     */
    @Override
    public Map<String, Object> getOverviewStatistics()
    {
        Map<String, Object> result = new HashMap<>();

        // 基础统计数据
        result.put("totalStudents", statisticsMapper.countTotalStudents());
        result.put("totalTeachers", statisticsMapper.countTotalTeachers());
        result.put("totalTopics", statisticsMapper.countTotalTopics());
        result.put("approvedTopics", statisticsMapper.countApprovedTopics());
        result.put("totalApplications", statisticsMapper.countTotalApplications());
        result.put("acceptedApplications", statisticsMapper.countAcceptedApplications());
        result.put("totalChangeRequests", statisticsMapper.countTotalChangeRequests());

        // 各状态题目数量
        result.put("topicsByStatus", statisticsMapper.countTopicsByStatus());

        // 各状态申请数量
        result.put("applicationsByStatus", statisticsMapper.countApplicationsByStatus());

        // 计算整体录取率
        int totalApplications = statisticsMapper.countTotalApplications();
        int acceptedApplications = statisticsMapper.countAcceptedApplications();
        double overallAcceptanceRate = totalApplications > 0
                ? Math.round(acceptedApplications * 10000.0 / totalApplications) / 100.0
                : 0.0;
        result.put("overallAcceptanceRate", overallAcceptanceRate);

        return result;
    }

    /**
     * 获取题目相关统计
     */
    @Override
    public Map<String, Object> getTopicStatistics()
    {
        Map<String, Object> result = new HashMap<>();

        // 难度分布
        result.put("difficultyDistribution", statisticsMapper.countTopicsByDifficulty());

        // 审核状态分布
        result.put("auditStatusDistribution", statisticsMapper.countTopicsByAuditStatus());

        // 热度排行(前10)
        result.put("popularityRanking", statisticsMapper.getTopicPopularityRanking(10));

        // 录取率排行(前10)
        result.put("acceptanceRanking", statisticsMapper.getTopicAcceptanceRanking(10));

        // 标签统计(处理JSON数组)
        Map<String, Integer> tagCount = new HashMap<>();
        List<String> allTagsJson = statisticsMapper.getAllTopicTags();
        for (String tagsJson : allTagsJson) {
            if (tagsJson != null && !tagsJson.trim().isEmpty()) {
                try {
                    JSONArray tags = JSON.parseArray(tagsJson);
                    for (Object tag : tags) {
                        String tagStr = tag.toString();
                        tagCount.put(tagStr, tagCount.getOrDefault(tagStr, 0) + 1);
                    }
                } catch (Exception e) {
                    // 忽略JSON解析错误
                }
            }
        }

        // 转换为List并按数量排序
        List<Map<String, Object>> tagDistribution = tagCount.entrySet().stream()
                .map(entry -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("name", entry.getKey());
                    map.put("value", entry.getValue());
                    return map;
                })
                .sorted((a, b) -> ((Integer)b.get("value")).compareTo((Integer)a.get("value")))
                .limit(15) // 只取前15个标签
                .collect(Collectors.toList());

        result.put("tagDistribution", tagDistribution);

        return result;
    }

    /**
     * 获取教师相关统计
     */
    @Override
    public Map<String, Object> getTeacherStatistics()
    {
        Map<String, Object> result = new HashMap<>();

        // 指导学生数排行(前10)
        result.put("studentRanking", statisticsMapper.getTeacherStudentRanking(10));

        // 题目发布数排行(前10)
        result.put("topicRanking", statisticsMapper.getTeacherTopicRanking(10));

        // 职称分布
        result.put("titleDistribution", statisticsMapper.countTeachersByTitle());

        // 录取率排行(前10,至少有3个申请)
        result.put("acceptanceRanking", statisticsMapper.getTeacherAcceptanceRanking(10));

        // 指导学生数分布
        result.put("studentDistribution", statisticsMapper.getTeacherStudentDistribution());

        return result;
    }

    /**
     * 获取学生相关统计
     */
    @Override
    public Map<String, Object> getStudentStatistics()
    {
        Map<String, Object> result = new HashMap<>();

        // 年级分布
        result.put("gradeDistribution", statisticsMapper.countStudentsByGrade());

        // 专业分布(前10)
        result.put("majorDistribution", statisticsMapper.countStudentsByMajor());

        // 录取状态
        Map<String, Object> acceptanceStatus = statisticsMapper.getStudentAcceptanceStatus();
        result.put("acceptanceStatus", acceptanceStatus);

        // 计算百分比 - 添加空值保护
        int totalStudents = acceptanceStatus.get("totalStudents") != null ?
                ((Number) acceptanceStatus.get("totalStudents")).intValue() : 0;
        int acceptedStudents = acceptanceStatus.get("acceptedStudents") != null ?
                ((Number) acceptanceStatus.get("acceptedStudents")).intValue() : 0;
        int pendingStudents = acceptanceStatus.get("pendingStudents") != null ?
                ((Number) acceptanceStatus.get("pendingStudents")).intValue() : 0;
        int notAppliedStudents = acceptanceStatus.get("notAppliedStudents") != null ?
                ((Number) acceptanceStatus.get("notAppliedStudents")).intValue() : 0;

        Map<String, Object> acceptanceStatusPercent = new HashMap<>();
        acceptanceStatusPercent.put("accepted", totalStudents > 0 ? Math.round(acceptedStudents * 10000.0 / totalStudents) / 100.0 : 0);
        acceptanceStatusPercent.put("pending", totalStudents > 0 ? Math.round(pendingStudents * 10000.0 / totalStudents) / 100.0 : 0);
        acceptanceStatusPercent.put("notApplied", totalStudents > 0 ? Math.round(notAppliedStudents * 10000.0 / totalStudents) / 100.0 : 0);
        result.put("acceptanceStatusPercent", acceptanceStatusPercent);

        // GPA分布
        result.put("gpaDistribution", statisticsMapper.getStudentGpaDistribution());

        return result;
    }

    /**
     * 获取申请相关统计
     */
    @Override
    public Map<String, Object> getApplicationStatistics()
    {
        Map<String, Object> result = new HashMap<>();

        // 第一志愿录取率
        Map<String, Object> firstPriorityRate = statisticsMapper.getFirstPriorityAcceptanceRate();
        result.put("firstPriorityRate", firstPriorityRate);

        // 第二志愿录取率
        Map<String, Object> secondPriorityRate = statisticsMapper.getSecondPriorityAcceptanceRate();
        result.put("secondPriorityRate", secondPriorityRate);

        // 志愿对比数据 - 字段名统一并添加空值保护
        List<Map<String, Object>> priorityComparison = new ArrayList<>();

        Map<String, Object> first = new HashMap<>();
        first.put("priority", 1);
        first.put("totalApplications", firstPriorityRate.getOrDefault("totalApplications", 0));
        first.put("acceptedApplications", firstPriorityRate.getOrDefault("acceptedCount", 0));
        first.put("acceptanceRate", firstPriorityRate.getOrDefault("acceptanceRate", 0.0));
        priorityComparison.add(first);

        Map<String, Object> second = new HashMap<>();
        second.put("priority", 2);
        second.put("totalApplications", secondPriorityRate.getOrDefault("totalApplications", 0));
        second.put("acceptedApplications", secondPriorityRate.getOrDefault("acceptedCount", 0));
        second.put("acceptanceRate", secondPriorityRate.getOrDefault("acceptanceRate", 0.0));
        priorityComparison.add(second);

        result.put("priorityComparison", priorityComparison);

        // 近30天申请趋势
        result.put("applicationTrend", statisticsMapper.getApplicationTrend(30));

        // 近30天录取趋势
        result.put("acceptanceTrend", statisticsMapper.getAcceptanceTrend(30));

        // 申请审核平均时长
        result.put("averageReviewTime", statisticsMapper.getAverageReviewTime());

        return result;
    }

    /**
     * 获取变更申请统计
     */
    @Override
    public Map<String, Object> getChangeRequestStatistics()
    {
        Map<String, Object> result = new HashMap<>();

        // 状态分布
        result.put("statusDistribution", statisticsMapper.countChangeRequestsByStatus());

        // 通过率
        result.put("passRate", statisticsMapper.getChangeRequestPassRate());

        // 近30天趋势
        result.put("trend", statisticsMapper.getChangeRequestTrend(30));

        return result;
    }

    /**
     * 获取时间趋势分析
     */
    @Override
    public Map<String, Object> getTimeTrendStatistics()
    {
        Map<String, Object> result = new HashMap<>();

        // 近30天题目发布趋势
        result.put("topicPublishTrend", statisticsMapper.getTopicPublishTrend(30));

        // 近30天申请趋势
        result.put("applicationTrend", statisticsMapper.getApplicationTrend(30));

        // 近30天录取趋势
        result.put("acceptanceTrend", statisticsMapper.getAcceptanceTrend(30));

        // 近12个月申请趋势
        result.put("monthlyApplicationTrend", statisticsMapper.getMonthlyApplicationTrend());

        // 近12个月录取趋势
        result.put("monthlyAcceptanceTrend", statisticsMapper.getMonthlyAcceptanceTrend());

        return result;
    }

    /**
     * 获取完整的仪表板数据(包含所有统计)
     */
    @Override
    public Map<String, Object> getDashboardData()
    {
        Map<String, Object> dashboard = new HashMap<>();

        // 添加所有统计数据
        dashboard.put("overview", getOverviewStatistics());
        dashboard.put("topic", getTopicStatistics());
        dashboard.put("teacher", getTeacherStatistics());
        dashboard.put("student", getStudentStatistics());
        dashboard.put("application", getApplicationStatistics());
        dashboard.put("changeRequest", getChangeRequestStatistics());
        dashboard.put("timeTrend", getTimeTrendStatistics());

        return dashboard;
    }
}